#pragma once

#include <condition_variable>
#include <mutex>
#include <queue>

namespace flashpp {

template<typename T>
class BlockingQueue {
 public:
  void push(T const&& data) {
    {
      std::lock_guard<std::mutex> lock(guard);
      queue.push(data);
    }
    cv.notify_one();
  }

  void take(T& data) {
    std::unique_lock<std::mutex> lock(guard);
    while (queue.empty()) {
      cv.wait(lock);
    }

    data = queue.front();
    queue.pop();
  }

 private:
  std::queue<T> queue;
  std::mutex guard;
  std::condition_variable cv;
};

} // namespace flashpp